﻿using System.Linq;
using ReBot.API;
using System.Collections.Generic;

namespace Drood
{
    [Rotation("Druid Boomkin", "Pasterke", WoWClass.Druid, Specialization.DruidBalance, 40, 35, false, 0)]
    public class DruidBalance : CombatRotation
    {
        public DruidBalance()
        {
            GroupBuffs = new string[]
			{
				"Mark of the Wild"
			};
            PullSpells = new string[]
			{
                "Sunfire",
				"Moonfire",
                "Wrath",
			};

            DismountSpell = "Moonkin Form";
        }


        public override bool OutOfCombat()
        {
            if (CastSelf("Rejuvenation", () => Me.HealthFraction <= 0.75 && !HasAura("Rejuvenation"))) return true;
            if (CastSelfPreventDouble("Healing Touch", () => Me.HealthFraction <= 0.5)) return true;
            if (CastSelf("Remove Corruption", () => Me.Auras.Any(x => x.IsDebuff && "Curse,Poison".Contains(x.DebuffType)))) return true;

            if (CastSelf("Mark of the Wild", () => !HasAura("Mark of the Wild")
                && !HasAura("Blessing of Kings")
                && !HasAura("Legacy of the Emperor"))) return true;

            if (CastSelf("Cat Form", () => Me.MovementSpeed != 0 && !Me.IsSwimming && Me.DisplayId == Me.NativeDisplayId && Me.DistanceTo(API.GetNaviTarget()) > 40)) return true;

            return false;
        }

        public override void Combat()
        {
            if (CastSelf("Moonkin Form", () => !Me.HasAura("Moonkin Form"))) return;

            if (CastSelf("Rejuvenation", () => Me.HealthFraction <= 0.75 && !HasAura("Rejuvenation"))) return;

            if (Cast("Mighty Bash", () => Me.Target != null
                && Me.Target.IsValid
                && Me.Target.Distance <= 5
                && Me.Target.IsCastingAndInterruptible())) return;

            if (Cast("Typhoon", () => Target.CanParticipateInCombat
                && Target.IsCastingAndInterruptible()
                && Target.CombatRange < 30
                && SpellCooldown("Typhoon") <= 0)) return;

            CastSelf("Barkskin", () => Me.HealthFraction < 0.7 && SpellCooldown("Barkskin") <= 0);

            if (Cast("Solar Beam", () => Target.IsCastingAndInterruptible() && SpellCooldown("Solar Beam") <= 0)) return;

            CastSelf("Celestial Alignment", () => isHard(Target) >= 4 && Target.IsInCombatRangeAndLoS && SpellCooldown("Celestial Alignment") <= 0);

            if (CastOnTerrain("Ursol's Vortex", Me.Target.Position, () => Me.Target != null
                && Me.Target.IsValid
                && Me.Target.CombatRange > 10
                && SpellCooldown("Ursol's Vortex") <= 0)) return;

            if (Cast("Force of Nature", () => HasSpell("Force of Nature")
                && Me.Target != null
                && Me.Target.IsValid
                && isHard(Me.Target) > 1)) return;

            if (Cast("Moonfire", () => Me.GetPower(WoWPowerType.DruidEclipse) <= 0
                && targetsWithoutDots != null
                && UnFriendlyRangeTargets <= 5, targetsWithoutDots)) return;

            if (Cast("Sunfire", () => Me.GetPower(WoWPowerType.DruidEclipse) > 0
                && targetsWithoutDots != null
                && UnFriendlyRangeTargets <= 5, targetsWithoutDots)) return;

            if (Cast("Starsurge", () => UnFriendlyRangeTargets <= 5
                && SpellCooldown("Starsurge") <= 0
                && SpellCharges("Starsurge") >= 2
                && Me.Target != null
                && Me.Target.IsValid, Me.Target)) return;

            if (Cast("Starfall", () => UnFriendlyRangeTargets > 5
                && SpellCooldown("Starfall") <= 0
                && SpellCharges("Starfall") >= 2
                && Me.Target != null
                && Me.Target.IsValid, Me.Target)) return;

            if (Cast("Starfire", () => Me.GetPower(WoWPowerType.DruidEclipse) <= 0
                && Me.Target != null
                && Me.Target.IsValid, Me.Target)) return;

            if (Cast("Wrath", () => Me.Target != null && Me.Target.IsValid, Me.Target)) return;

        }
        #region findtarget
        public bool needNewTarget()
        {
            if (Me.Target != null && !Me.Target.IsDead && !Me.Target.IsFriendly && Me.Target.IsEnemy) return false;
            if (Me.Target != null && Me.Target.Distance > 12 && UnFriendlyMeleeTargets > 0) return true;
            if ((Me.Target == null || Me.Target.IsDead || Me.Target.IsFriendly || !Me.Target.IsAttackable || !Me.Target.IsValid)
                && Me.InCombat
                && UnFriendlyMeleeTargets == 0) return true;
            return false;
        }
        public List<UnitObject> findRangeTargets
        {
            get
            {
                var t = new List<UnitObject>();
                t = API.Units.Where(p => p != null
                        && !p.IsDead
                        && !p.IsFriendly
                        && !p.IsPet
                        && p.IsAttackable
                        && p.IsInLoS
                        && p.DistanceSquared <= 40).OrderBy(p => p.Distance).ToList();
                return t;
            }
        }

        public int UnFriendlyRangeTargets { get { return findRangeTargets.Count(); } }

        public List<UnitObject> findMeleeTargets
        {
            get
            {
                var t = new List<UnitObject>();
                t = API.Units.Where(p => p != null
                        && !p.IsDead
                        && !p.IsFriendly
                        && !p.IsPet
                        && p.IsAttackable
                        && p.IsInLoS
                        && p.DistanceSquared <= 8).OrderBy(p => p.Distance).ToList();
                return t;
            }
        }

        public int UnFriendlyMeleeTargets { get { return findMeleeTargets.Count(); } }

        public string checkBuff()
        {
            if (Me.GetPower(WoWPowerType.DruidEclipse) > 0) return "Sunfire";
            return "Moonfire";
        }

        public UnitObject targetsWithoutDots
        {
            get
            {
                var t = API.Units.Where(p => p != null
                        && !p.IsDead
                        && !p.InCombat
                        && !p.IsPet
                        && p.IsAttackable
                        && p.IsInLoS
                        && !Me.IsNotInFront(p)
                        && !p.HasAura(checkBuff())
                        && p.DistanceSquared <= 40).OrderBy(p => p.Distance).FirstOrDefault();
                return t != null ? t : null;
            }
        }
        #endregion

        public int isHard(UnitObject target)
        {
            if (API.MapInfo.Type == MapType.Arena || API.MapInfo.Type == MapType.PvP)
            {
                return 5;
            }
            if (API.MapInfo.Type == MapType.Instance || API.MapInfo.Type == MapType.Raid)
            {
                if (Target.MaxHealth > Me.MaxHealth * 8) return 5;
                if (Target.MaxHealth > Me.MaxHealth * 5.5) return 4;
                if (Target.MaxHealth > Me.MaxHealth * 4.5) return 3;
                if (Target.MaxHealth > Me.MaxHealth * 3.5) return 2;
                if (Target.MaxHealth > Me.MaxHealth * 2.5) return 1;
            }
            if (API.MapInfo.Type == MapType.Normal)
            {
                if (Target.MaxHealth > Me.MaxHealth * 4.5) return 4;
                if (Target.MaxHealth > Me.MaxHealth * 3.5) return 3;
                if (Target.MaxHealth > Me.MaxHealth * 2.5) return 2;
                if (Target.MaxHealth > Me.MaxHealth * 1.5) return 1;
            }
            return 0;
        }
    }
}
